
Chapter 10  Disk Internals

  MS-DOS disks are organized according to a rather rigid scheme that is
  easily understood and therefore easily manipulated. Although you will
  probably never need to access the special control areas of a disk
  directly, an understanding of their internal structure leads to a better
  understanding of the behavior and performance of MS-DOS as a whole.

  From the application programmer's viewpoint, MS-DOS presents disk devices
  as logical volumes that are associated with a drive code (A, B, C, and so
  on) and that have a volume name (optional), a root directory, and from
  zero to many additional directories and files. MS-DOS shields the
  programmer from the physical characteristics of the medium by providing a
  battery of disk services through Int 21H. Using these services, the
  programmer can create, open, read, write, close, and delete files in a
  uniform way, regardless of the disk drive's size, speed, number of
  read/write heads, number of tracks, and so forth.

  Requests from an application program for file operations actually go
  through two levels of translation before resulting in the physical
  transfer of data between the disk device and random-access memory:

  1.  Beneath the surface, MS-DOS views each logical volume, whether it is
      an entire physical unit such as a floppy disk or only a part of a
      fixed disk, as a continuous sequence of logical sectors, starting at
      sector 0. (A logical disk volume can also be implemented on other
      types of storage. For example, RAM disks map a disk structure onto an
      area of random-access memory.) MS-DOS translates an application
      program's Int 21H file-management requests into requests for transfers
      of logical sectors, using the information found in the volume's
      directories and allocation tables. (For those rare situations where it
      is appropriate, programs can also access logical sectors directly with
      Int 25H and Int 26H.)

  2.  MS-DOS then passes the requests for logical sectors to the disk
      device's driver, which maps them onto actual physical addresses (head,
      track, and sector). Disk drivers are extremely hardware dependent and
      are always written in assembly language for maximum speed. In most
      versions of MS-DOS, a driver for IBM-compatible floppy- and fixed-disk
      drives is built into the MS-DOS BIOS module (IO.SYS) and is always
      loaded during system initialization; you can install additional
      drivers for non-IBM-compatible disk devices by including the
      appropriate DEVICE directives in the CONFIG.SYS file.

  Each MS-DOS logical volume is divided into several fixed-size control
  areas and a files area (Figure 10-1). The size of each control area
  depends on several factorsthe size of the volume and the version of
  FORMAT used to initialize the volume, for examplebut all of the
  information needed to interpret the structure of a particular logical
  volume can be found on the volume itself in the boot sector.

  ++
  |                      Boot sector                      |
  |                     Reserved area                     |
  ++
  |               File allocation table #1                |
  ++
  |           Possible additional copies of FAT           |
  ++
  |                    Root directory                     |
  ++
  |                                                       |
  |                      Files area                       |
  |                                                       |
  ++

  Figure 10-1.  Map of a typical MS-DOS logical volume. The boot sector
  (logical sector 0) contains the OEM identification, BIOS parameter block
  (BPB), and disk bootstrap. The remaining sectors are divided among an
  optional reserved area, one or more copies of the file allocation table,
  the root directory, and the files area.


The Boot Sector

  Logical sector 0, known as the boot sector, contains all of the critical
  information regarding the disk mediu 's characteristics (Figure 10-2).
  The first byte in the sector is always an 80x86 jump instructioneither a
  normal intrasegment JMP (opcode 0E9H) followed by a 16-bit displacement or
  a "short" JMP (opcode 0EBH) followed by an 8-bit displacement and then by
  an NOP (opcode 90H). If neither of these two JMP opcodes is present, the
  disk has not been formatted or was not formatted for use with MS-DOS. (Of
  course, the presence of the JMP opcode does not in itself ensure that the
  disk has an MS-DOS format.)

  Following the initial JMP instruction is an 8-byte field that is reserved
  by Microsoft for OEM identification. The disk-formatting program, which is
  specialized for each brand of computer, disk controller, and medium, fills
  in this area with the name of the computer manufacturer and the
  manufacturer's internal MS-DOS version number.

  00H ++
      |             E9 XX XX or EB XX 90              |
  03H ++
      |             OEM name and version              |
      |                   (8 bytes)                   |
  OBH +++
      |          Bytes per sector (2 bytes)           | |
  ODH ++ |
      |     Sectors per allocation unit (1 byte)      | |
  0EH ++ |
      |   Reserved sectors, starting at 0 (2 bytes)   | |
  10H ++ |
      |            Number of FATs (1 byte)            | B
  11H ++ P
      |  Number of root-directory entries (2 bytes)   | B
  13H ++ |
      |   Total sectors in logical volume (2 bytes)   | |
  15H ++ | MS-DOS
      |             Media descriptor byte             | | version 2.0
  16H ++ |
      |      Number of sectors per FAT (2 bytes)      | |
  18H ++=+
      |          Sectors per track (2 bytes)          | |
  1AH ++ |
      |           Number of heads (2 bytes)           | | MS-DOS
  1CH ++ | version 3.0
      |      Number of hidden sectors (4 bytes)       |=+
  20H ++ | MS-DOS
      |        Total sectors in logical volume        | | version 4.0
      |      (MS-DOS 4.0 and volume size >32 MB)      | |
  24H ++=+
      |             Physical drive number             | |
  25H ++ |
      |                   Reserved                    | |
  26H ++ |
      |     Extended boot signature record (29H)      | | Additional
  27H ++ | MS-DOS 4.0
      |            32-bit binary volume ID            | | information
  2BH ++ |
      |            Volume label (11 bytes)            | |
  36H ++ |
      |              Reserved (8 bytes)               | |
  3EH +++
      |                   Bootstrap                   |
      ++

  Figure 10-2.  Map of the boot sector of an MS-DOS disk. Note the JMP at
  offset 0, the OEM identification field, the MS-DOS version 2 compatible
  BIOS parameter block (bytes 0BH17H), the three additional WORD fields for
  MS-DOS version 3, the double-word number-of-sectors field and 32-bit
  binary volume ID for MS-DOS version 4.0, and the bootstrap code.

  The third major component of the boot sector is the BIOS parameter block
  (BPB) in bytes 0BH through 17H. (Additional fields are present in MS-DOS
  versions 3.0 and later.) This data structure describes the physical disk
  characteristics and allows the device driver to calculate the proper
  physical disk address for a given logical-sector number; it also contains
  information that is used by MS-DOS and various system utilities to
  calculate the address and size of each of the disk control areas (file
  allocation tables and root directory).

  The final element of the boot sector is the disk bootstrap routine. The
  disk bootstrap is usually read into memory by the ROM bootstrap, which is
  executed automatically when the computer is turned on. The ROM bootstrap
  is usually just smart enough to home the head of the disk drive (move it
  to track 0), read the first physical sector into RAM at a predetermined
  location, and jump to it. The disk bootstrap is more sophisticated. It
  calculates the physical disk address of the beginning of the files area,
  reads the files containing the operating system into memory, and transfers
  control to the BIOS module at location 0070:0000H. (See Chapter 2.)

  Figures 10-3 and 10-4 show a partial hex dump and disassembly of a
  PC-DOS 3.3 floppy-disk boot sector.

  
         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
  0000  EB 34 90 49 42 4D 20 20 33 2E 33 00 02 02 01 00  .4.IBM  3.3.....
  0010  02 70 00 D0 02 FD 02 00 09 00 02 00 00 00 00 00  .p..............
  0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 12  ................
  0030  00 00 00 00 01 00 FA 33 C0 8E D0 BC 00 7C 16 07  .......3.....|..
        .
        .
        .
  01C0  0D 0A 44 69 73 6B 20 42 6F 6F 74 20 66 61 69 6C  ..Disk Boot fail
  01D0  75 72 65 0D 0A 00 49 42 4D 42 49 4F 20 20 43 4F  ure...IBMBIO  CO
  01E0  4D 49 42 4D 44 4F 53 20 20 43 4F 4D 00 00 00 00  MIBMDOS  COM....
  01F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA  ..............U.
  

  Figure 10-3.  Partial hex dump of the boot sector (track 0, head 0, sector
  1) of a PC-DOS version 3.3 floppy disk. This sector contains the OEM
  identification, a copy of the BIOS parameter block describing the medium,
  and the bootstrap routine that reads the BIOS into memory and transfers
  control to it. See also Figures 10-2 and 10-4.

  
          jmp     $+54            ; jump to bootstrap
          nop

          db      'IBM  3.3'      ; OEM identification

                                  ; BIOS parameter block
          dw      512             ; bytes per sector
          db      2               ; sectors per cluster
          dw      1               ; reserved sectors
          db      2               ; number of FATs
          dw      112             ; root directory entries
          dw      720             ; total sectors
          db      0fdh            ; media descriptor byte
          dw      2               ; sectors per FAT

          dw      9               ; sectors per track
          dw      2               ; number of heads
          dd      0               ; hidden sectors
          .
          .
          .
  

  Figure 10-4.  Partial disassembly of the boot sector shown in Figure
  10-3.


The Reserved Area

  The boot sector is actually part of a reserved area that can span from one
  to several sectors. The reserved-sectors word in the BPB, at offset 0EH in
  the boot sector, describes the size of this area. Remember that the number
  in the BPB field includes the boot sector itself, so if the value is 1 (as
  it is on IBM PC floppy disks), the length of the reserved area is actually
  0 sectors.


The File Allocation Table

  When a file is created or extended, MS-DOS assigns it groups of disk
  sectors from the files area in powers of 2. These are known as allocation
  units or clusters. The number of sectors per cluster for a given medium is
  defined in the BPB and can be found at offset 0DH in the disk's boot
  sector. Below are some example cluster sizes:

  Disk type                     Power of 2    Sectors/cluster
  
  5.25" 180 KB floppy disk      0             1
  5.25" 360 KB floppy disk      1             2
  PC/AT fixed disk              2             4
  PC/XT fixed disk              3             8
  

  The file allocation table (FAT) is divided into fields that correspond
  directly to the assignable clusters on the disk. These fields are 12 bits
  in MS-DOS versions 1 and 2 and may be either 12 bits or 16 bits in
  versions 3.0 and later, depending on the size of the medium (12 bits if
  the disk contains fewer than 4087 clusters, 16 bits otherwise).

  The first two fields in the FAT are always reserved. On IBM-compatible
  media, the first 8 bits of the first reserved FAT entry contain a copy of
  the media descriptor byte, which is also found in the BPB in the boot
  sector. The second, third, and (if applicable) fourth bytes, which
  constitute the remainder of the first two reserved FAT fields, always
  contain 0FFH. The currently defined IBM-format media descriptor bytes are
  as follows:

                                                             MS-DOS version
                                                             where first
  Descriptor     Medium                                      supported
  
  0F0H           3.5" floppy disk, 2-sided, 18-sector        3.3
  0F8H           Fixed disk                                  2.0
  0F9H           5.25" floppy disk, 2-sided, 15-sector       3.0
                 3.5" floppy disk, 2-sided, 9-sector         3.2
  0FCH           5.25" floppy disk, 1-sided, 9-sector        2.0
  0FDH           5.25" floppy disk, 2-sided, 9-sector        2.0
                 8" floppy disk, 1-sided, single-density
  0FEH           5.25" floppy disk, 1-sided, 8-sector        1.0
                 8" floppy disk, 1-sided, single-density
                 8" floppy disk, 2-sided, double-density
  0FFH           5.25" floppy disk, 2-sided, 8-sector        1.1
  

  The remainder of the FAT entries describe the use of their corresponding
  disk clusters. The contents of the FAT fields are interpreted as follows:

  Value              Meaning
  
  (0)000H            Cluster available
  (F)FF0(F)FF6H     Reserved cluster
  (F)FF7H            Bad cluster, if not part of chain
  (F)FF8(F)FFFH     Last cluster of file
  (X)XXX             Next cluster in file
  

  Each file's entry in a directory contains the number of the first cluster
  assigned to that file, which is used as an entry point into the FAT. From
  the entry point on, each FAT slot contains the cluster number of the next
  cluster in the file, until a last-cluster mark is encountered.

  At the computer manufacturer's option, MS-DOS can maintain two or more
  identical copies of the FAT on each volume. MS-DOS updates all copies
  simultaneously whenever files are extended or the directory is modified.
  If access to a sector in a FAT fails due to a read error, MS-DOS tries the
  other copies until a successful disk read is obtained or all copies are
  exhausted. Thus, if one copy of the FAT becomes unreadable due to wear or
  a software accident, the other copies may still make it possible to
  salvage the files on the disk. As part of its procedure for checking the
  integrity of a disk, the CHKDSK program compares the multiple copies
  (usually two) of the FAT to make sure they are all readable and
  consistent.


The Root Directory

  Following the file allocation tables is an area known in MS-DOS versions
  2.0 and later as the root directory. (Under MS-DOS version 1, it was the
  only directory on the disk.) The root directory contains 32-byte entries
  that describe files, other directories, and the optional volume label
  (Figure 10-5). An entry beginning with the byte value E5H is available
  for reuse; it represents a file or directory that has been erased. An
  entry beginning with a null (zero) byte is the logical end-of-directory;
  that entry and all subsequent entries have never been used.

  00H ++
      |           Filename           | Note 1
  08H ++
      |          Extension           |
  0BH ++
      |        File attribute        | Note 2
  0CH ++
      |           Reserved           |
  16H ++
      | Time created or last updated | Note 3
  18H ++
      | Date created or last updated | Note 4
  1AH ++
      |       Starting cluster       |
  1CH ++
      |      File size, 4 bytes      | Note 5
  20H ++

  Figure 10-5.  Format of a single entry in a disk directory. Total length
  is 32 bytes (20H bytes).

  
  Notes for Figure 10-5
    1.  The first byte of the filename field of a directory entry may
        contain the following special information:

    Value             Meaning
    
    00H               Directory entry has never been used; end of occupied
                      portion of directory.
    05H               First character of filename is actually E5H.
    2EH               Entry is an alias for the current or parent directory.
                      If the next byte is also 2EH, the cluster field
                      contains the cluster number of the parent directory
                      (zero if the parent directory is the root directory).
    E5H               File has been erased.
    

    2.  The attribute byte of the directory entry is mapped as follows:

    Bit               Meaning
    
    0                 Read-only; attempts to open file for write or to
                      delete file will fail.
    1                 Hidden file; excluded from normal searches.
    2                 System file; excluded from normal searches.
    3                 Volume label; can exist only in root directory.
    4                 Directory; excluded from normal searches.
    5                 Archive bit; set whenever file is modified.
    6                 Reserved.
    7                 Reserved.
    

    3.  The time field is encoded as follows:

    Bits              Contents
    
    00H04H           Binary number of 2-second increments (029,
                      corresponding to 058 seconds)
    05H0AH           Binary number of minutes (059)
    0BH0FH           Binary number of hours (023)
    

    4.  The date field is encoded as follows:

    Bits              Contents
    
    00H04H           Day of month (131)
    05H08H           Month (112)
    09H0FH           Year (relative to 1980)
    

    5.  The file-size field is interpreted as a 4-byte integer, with the
        low-order 2 bytes of the number stored first.

  

  The root directory has a number of special properties. Its size and
  position are fixed and are determined by the FORMAT program when a disk is
  initialized. This information can be obtained from the boot sector's BPB.
  If the disk is bootable, the first two entries in the root directory
  always describe the files containing the MS-DOS BIOS and the MS-DOS
  kernel. The disk bootstrap routine uses these entries to bring the
  operating system into memory and start it up.

  Figure 10-6 shows a partial hex dump of the first sector of the root
  directory on a bootable PC-DOS 3.3 floppy disk.

  
         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
  0000  49 42 4D 42 49 4F 20 20 43 4F 4D 27 00 00 00 00  IBMBIO  COM'....
  0010  00 00 00 00 00 00 00 60 72 0E 02 00 54 56 00 00  .......'r...TV..
  0020  49 42 4D 44 4F 53 20 20 43 4F 4D 27 00 00 00 00  IBMDOS  COM'....
  0030  00 00 00 00 00 00 00 60 71 0E 18 00 CF 75 00 00  .......'q....u..
  0040  43 4F 4D 4D 41 4E 44 20 43 4F 4D 20 00 00 00 00  COMMAND COM ....
  0050  00 00 00 00 00 00 00 60 71 0E 36 00 DB 62 00 00  .......'q.6..b..
  0060  42 4F 4F 54 44 49 53 4B 20 20 20 28 00 00 00 00  BOOTDISK   (....
  0070  00 00 00 00 00 00 A1 00 21 00 00 00 00 00 00 00  ........!.......
  0080  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0090  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
        .
        .
        .
  

  Figure 10-6.  Partial hex dump of the first sector of the root directory
  for a PC-DOS 3.3 disk containing the three system files and a volume
  label.


The Files Area

  The remainder of the volume after the root directory is known as the files
  area. MS-DOS views the sectors in this area as a pool of clusters, each
  containing one or more logical sectors, depending on the disk format. Each
  cluster has a corresponding entry in the FAT that describes its current
  use: available, reserved, assigned to a file, or unusable (because of
  defects in the medium). Because the first two fields of the FAT are
  reserved, the first cluster in the files area is assigned the number 2.

  When a file is extended under versions 1 and 2, MS-DOS searches the FAT
  from the beginning until it finds a free cluster (designated by a zero FAT
  field); it then changes that FAT field to a last-cluster mark and updates
  the previous last cluster of the file's chain to point to the new last
  cluster. Under versions 3.0 and later, however, MS-DOS searches the FAT
  from the most recently allocated cluster; this reduces file fragmentation
  and improves overall access times.

  Directories other than the root directory are simply a special type of
  file. Their storage is allocated from the files area, and their contents
  are 32-byte entriesin the same format as those used in the root
  directorythat describe files or other directories. Directory entries
  that describe other directories contain an attribute byte with bit 4 set,
  zero in the file-length field, and the date and time that the directory
  was created (Figure 10-7). The first cluster field points, of course, to
  the first cluster in the files area that belongs to the directory. (The
  directory's other clusters can be found only by tracing through the FAT.)

  All directories except the root directory contain two special directory
  entries with the names . and ... MS-DOS puts these entries in place when
  it creates a directory, and they cannot be deleted. The . entry is an
  alias for the current directory; its cluster field points to the cluster
  in which it is found. The .. entry is an alias for the directory's parent
  (the directory immediately above it in the tree structure); its cluster
  field points to the first cluster of the parent directory. If the parent
  is the root directory, the cluster field of the .. entry contains zero
  (Figure 10-8).

  
        .
        .
        .
  0080  4D 59 44 49 52 20 20 20 20 20 20 10 00 00 00 00  MYDIR      .....
  0090  00 00 00 00 00 00 87 9A 9B 0A 2A 00 00 00 00 00  ..........*.....
        .
        .
        .
  

  Figure 10-7.  Extract from the root directory of an MS-DOS disk, showing
  the entry for a subdirectory named MYDIR. Bit 4 in the attribute byte is
  set, the cluster field points to the first cluster of the subdirectory
  file, the date and time stamps are valid, but the file length is zero.

  
         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
  0000  2E 20 20 20 20 20 20 20 20 20 20 10 00 00 00 00  .         .....
  0010  00 00 00 00 00 00 87 9A 9B 0A 2A 00 00 00 00 00  ..........*.....
  0020  2E 2E 20 20 20 20 20 20 20 20 20 10 00 00 00 00  ..        .....
  0030  00 00 00 00 00 00 87 9A 9B 0A 00 00 00 00 00 00  ................
  0040  4D 59 46 49 4C 45 20 20 44 41 54 20 00 00 00 00  MYFILE  DAT ....
  0050  00 00 00 00 00 00 98 9A 9B 0A 2B 00 15 00 00 00  ..........+.....
  0060  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0070  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
        .
        .
        .
  

  Figure 10-8.  Hex dump of the first block of the directory MYDIR. Note the
  . and .. entries. This directory contains exactly one file, MYFILE.DAT.


Interpreting the File Allocation Table

  Now that we understand how the disk is structured, let's see how we can
  use this knowledge to find a FAT position from a cluster number.

  If the FAT has 12-bit entries, use the following procedure:

  1.  Use the directory entry to find the starting cluster of the file in
      question.

  2.  Multiply the cluster number by 1.5.

  3.  Use the integral part of the product as the offset into the FAT and
      move the word at that offset into a register. Remember that a FAT
      position can span a physical disk-sector boundary.

  4.  If the product is a whole number, AND the register with 0FFFH.

  5.  Otherwise, "logical shift" the register right 4 bits.

  6.  If the result is a value from 0FF8H through 0FFFH, the file has no
      more clusters. Otherwise, the result is the number of the next cluster
      in the file.

  On disks with at least 4087 clusters formatted under MS-DOS version 3.0 or
  later, the FAT entries use 16 bits, and the extraction of a cluster number
  from the table is much simpler:

  1.  Use the directory entry to find the starting cluster of the file in
      question.

  2.  Multiply the cluster number by 2.

  3.  Use the product as the offset into the FAT and move the word at that
      offset into a register.

  4.  If the result is a value from 0FFF8H through 0FFFFH, the file has no
      more clusters. Otherwise, the result is the number of the next cluster
      in the file.

  To convert cluster numbers to logical sectors, subtract 2, multiply the
  result by the number of sectors per cluster, and add the logical-sector
  number of the beginning of the data area (this can be calculated from the
  information in the BPB).

  As an example, let's work out the disk location of the file IBMBIO.COM,
  which is the first entry in the directory shown in Figure 10-6. First, we
  need some information from the BPB, which is in the boot sector of the
  medium. (See Figures 10-3 and 10-4.) The BPB tells us that there are

    512 bytes per sector

    2 sectors per cluster

    2 sectors per FAT

    2 FATs

    112 entries in the root directory

  From the BPB information, we can calculate the starting logical-sector
  number of each of the disk's control areas and the files area by
  constructing a table, as follows:

                                                   Length       Sector
  Area                                             (sectors)    numbers
  
  Boot sector                                      1            00H
  2 FATs * 2 sectors/FAT                           4            01H04H
  112 directory entries                            7            05H0BH
    *32 bytes/entry
    /512 bytes/sector
  Total sectors occupied by bootstrap, FATs, and   12
  root directory
  

  Therefore, the first sector of the files area is 12 (0CH).

  The word at offset 01AH in the directory entry for IBMBIO.COM gives us the
  starting cluster number for that file: cluster 2. To find the
  logical-sector number of the first block in the file, we can follow the
  procedure given earlier:

  1.  Cluster number - 2 = 2 - 2 = 0.

  2.  Multiply by sectors per cluster = 0 * 2 = 0.

  3.  Add logical-sector number of start of the files area = 0 + 0CH = 0CH.

  So the calculated sector number of the beginning of the file IBMBIO.COM is
  0CH, which is exactly what we expect knowing that the FORMAT program
  always places the system files in contiguous sectors at the beginning of
  the data area.

  Now let's trace IBMBIO.COM's chain through the file allocation table
  (Figures 10-9 and 10-10). This will be a little tedious, but a detailed
  understanding of the process is crucial. In an actual program, we would
  first read the boot sector using Int 25H, then calculate the address of
  the FAT from the contents of the BPB, and finally read the FAT into
  memory, again using Int 25H.

  From IBMBIO.COM's directory entry, we already know that the first cluster
  in the file is cluster 2. To examine that cluster's entry in the FAT, we
  multiply the cluster number by 1.5, which gives 0003H as the FAT offset,
  and fetch the word at that offset (which contains 4003H). Because the
  product of the cluster and 1.5 is a whole number, we AND the word from the
  FAT with 0FFFH, yielding the number 3, which is the number of the second
  cluster assigned to the file.

  
         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
  0000  FD FF FF 03 40 00 05 60 00 07 80 00 09 A0 00 0B  ......'........
  0010  C0 00 0D E0 00 0F 00 01 11 20 01 13 40 01 15 60  ......... ....'
  0020  01 17 F0 FF 19 A0 01 1B C0 01 1D E0 01 1F 00 02  ................
  0030  21 20 02 23 40 02 25 60 02 27 80 02 29 A0 02 2B  ! .#.%'.'..)..+
        .
        .
        .
  

  Figure 10-9.  Hex dump of the first block of the file allocation table
  (track 0, head 0, sector 2) for the PC-DOS 3.3 disk whose root directory
  is shown in Figure 10-6. Notice that the first byte of the FAT contains
  the media descriptor byte for a 5.25-inch, 2-sided, 9-sector floppy disk.

  
  getfat    proc      near      ; extracts the FAT field
                                ; for a given cluster
                                ; call    AX = cluster #
                                ;      DS:BX = addr of FAT
                                ; returns AX = FAT field
                                ; other registers unchanged

            push      bx        ; save affected registers
            push      cx
            mov       cx,ax
            shl       ax,1      ; cluster * 2
            add       ax,cx     ; cluster * 3
            test      ax,1
            pushf               ; save remainder in Z flag
            shr       ax,1      ; cluster * 1.5
            add       bx,ax
            mov       ax,[bx]
            popf                ; was cluster * 1.5 whole number?
            jnz       getfat1   ; no, jump
            and       ax,0fffh  ; yes, isolate bottom 12 bits
            jmp       getfat2
  getfat1:  mov       cx,4      ; shift word right 4 bits
            shr       ax,cx
  getfat2:  pop       cx        ; restore registers and exit
            pop       bx
            ret
  getfat    endp
  

  Figure 10-10.  Assembly-language procedure to access the file allocation
  table (assumes 12-bit FAT fields). Given a cluster number, the procedure
  returns the contents of that cluster's FAT entry in the AX register. This
  simple example ignores the fact that FAT entries can span sector
  boundaries.

  To examine cluster 3's entry in the FAT, we multiply 3 by 1.5, which gives
  4.5, and fetch the word at offset 0004H (which contains 0040H). Because
  the product of 3 and 1.5 is not a whole number, we shift the word right
  4 bits, yielding the number 4, which is the number of the third cluster
  assigned to IBMBIO.COM.

  In this manner, we can follow the chain through the FAT until we come to a
  cluster (number 23, in this case) whose FAT entry contains the value
  0FFFH, which is an end-of-file marker in FATs with 12-bit entries.

  We have now established that the file IBMBIO.COM contains clusters 2
  through 23 (02H17H), from which we can calculate that logical sectors 0CH
  through 38H are assigned to the file. Of course, the last cluster may be
  only partially filled with actual data; the portion of the last cluster
  used is the remainder of the file's size in bytes (found in the directory
  entry) divided by the bytes per cluster.


Fixed-Disk Partitions

  Fixed disks have another layer of organization beyond the logical volume
  structure already discussed: partitions. The FDISK utility divides a fixed
  disk into one or more partitions consisting of an integral number of
  cylinders. Each partition can contain an independent file system and, for
  that matter, its own copy of an operating system.

  The first physical sector on a fixed disk (track 0, head 0, sector 1)
  contains the master boot record, which is laid out as follows:

  Bytes              Contents
  
  0001BDH           Reserved
  1BE1CDH           Partition #1 descriptor
  1CE1DDH           Partition #2 descriptor
  1DE1EDH           Partition #3 descriptor
  1EE1FDH           Partition #4 descriptor
  1FE1FFH           Signature word (AA55H)
  

  The partition descriptors in the master boot record define the size,
  location, and type of each partition, as follows:

  Byte(s)            Contents
  
  00H                Active flag (0 = not bootable, 80H = bootable)
  01H                Starting head
  02H03H            Starting cylinder/sector
  04H                Partition type
  00H                not used
  01H                FAT file system, 12-bit FAT entries
  04H                FAT file system, 16-bit FAT entries
  05H                extended partition
  06H                "huge partition" (MS-DOS versions 4.0 and later)
  05H                Ending head
  06H07H            Ending cylinder/sector
  08H0BH            Starting sector for partition, relative to beginning of
                     disk
  0CH0FH            Partition length in sectorsThe active flag, which
                     indicates that the partition is bootable, can be set on
                     only one partition at a time.
  

  MS-DOS treats partition types 1, 4, and 6 as normal logical volumes and
  assigns them their own drive identifiers during the system boot process.
  Partition type 5 can contain multiple logical volumes and has a special
  extended boot record that describes each volume. The FORMAT utility
  initializes MS-DOS fixed-disk partitions, creating the file system within
  the partition (boot record, file allocation table, root directory, and
  files area) and optionally placing a bootable copy of the operating system
  in the file system.

  Figure 10-11 contains a partial hex dump of a master block from a fixed
  disk formatted under PC-DOS version 3.3. This dump illustrates the
  partition descriptors for a normal partition with a 16-bit FAT and an
  extended partition.

  
  0000   .
         .
         .
  0180  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0190  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  01A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  01B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 01
  01C0  01 00 04 04 D1 02 11 00 00 00 EE FF 00 00 00 00
  01D0  C1 04 05 04 D1 FD 54 00 01 00 02 53 00 00 00 00
  01E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  01F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA
  

  Figure 10-11.  A partial hex dump of a master block from a fixed disk
  formatted under PC-DOS version 3.3. This disk contains two partitions. The
  first partition has a 16-bit FAT and is marked "active" to indicate that
  it contains a bootable copy of PC-DOS. The second partition is an
  "extended" partition. The third and fourth partition entries are not used
  in this example.



